package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/gin-gonic/gin"
	"pingce/api/learning"
	"pingce/core/helper"
	"pingce/core/logic"
	"pingce/voince"
)

var ini_path string
var port string
func main() {
	flag.StringVar(&ini_path, "conf", "", "数据库配置文件")
	flag.StringVar(&port, "port", "8080", "端口号")
	flag.Parse()

	StartServer()
}

func StartServer() {
	r := gin.Default()
	r.POST("/learning", func(c *gin.Context) {
		var postData learning.ReqParam
		if err := c.ShouldBind(&postData); err != nil {
			c.JSON(200, gin.H{
				"code": 1,
				"msg":  err.Error(),
			})
			return
		}

		res := logic.GetConfigGroup("system.youdao", ini_path)
		AppId := helper.GetVal(res, "tencent_appid")
		SecretID := helper.GetVal(res, "tencent_secret_id")
		SecretKey := helper.GetVal(res, "tencent_secret_key")

		if postData.Text == "" {
			c.JSON(200, gin.H{
				"code": 1,
				"msg":  "单词或者句子不能为空",
			})
			return
		}

		if postData.AudioFile == "" && postData.Fid == 0 {
			c.JSON(200, gin.H{
				"code": 1,
				"msg":  "音频文件不能为空",
			})
			return
		}

		if postData.Fid > 0 {
			path := logic.GetFilePath(postData.Fid)
			if path == "" {
				c.JSON(200, gin.H{
					"code": 1,
					"msg":  "无法找到该音频文件记录",
				})
				return
			}
			path = helper.GetRoot() + "/public/static/storage/" + path

			_, err := os.Stat(path)
			if err != nil {
				if os.IsNotExist(err) {
					c.JSON(200, gin.H{
						"code": 1,
						"msg":  "音频文件路径不存在",
					})
					return
				} else if os.IsPermission(err) {
					c.JSON(200, gin.H{
						"code": 1,
						"msg":  "该文件没有读权限",
					})
					return
				}
			}

			postData.AudioFile = path
		} else if postData.AudioFile != "" {
			path := helper.GetRoot() + "/public/static/storage/" + postData.AudioFile
			_, err := os.Stat(path)
			if err != nil {
				if os.IsNotExist(err) {
					c.JSON(200, gin.H{
						"code": 1,
						"msg":  "音频文件路径不存在",
					})
					return
				} else if os.IsPermission(err) {
					c.JSON(200, gin.H{
						"code": 1,
						"msg":  "该文件没有读权限",
					})
					return
				}
			}
			postData.AudioFile = path
		}

		if strings.LastIndex(postData.AudioFile, ".mp3") != -1 {
			res := mp3ToWav(postData.AudioFile)
			if !res {
				c.JSON(200, gin.H{
					"code": 1,
					"msg":  "格式转换失败",
				})
				return
			}
			postData.AudioFile = strings.ReplaceAll(postData.AudioFile, ".mp3", ".wav")
		}

		scoreCoeff := postData.ScoreCoeff
		if scoreCoeff <= 0 {
			scoreCoeff = 1.0
		}

		data, err := voince.RunVoince(&voince.Param{
			AppID:       AppId,
			SecretID:    SecretID,
			SecretKey:   SecretKey,
			AudioFile:   postData.AudioFile,
			VoiceFormat: 1,
			Text:        postData.Text,
			EvalMode:    postData.EvalMode,
			ScoreCoeff:  scoreCoeff,

			Loop:      false,
			ProxyURL:  "",
			ShowMsg:   true,
			SliceSize: 1600,
		}, 1)

		if err != nil {
			c.JSON(200, gin.H{
				"code": 1,
				"msg":  err.Error(),
			})
			return
		}

		if len(data) > 0 {
			for _, info := range data {
				var tmp map[string]any
				err = json.Unmarshal([]byte(info), &tmp)
				if err != nil {
					c.JSON(200, gin.H{
						"code": 1,
						"msg":  "转换格式失败",
					})
					return
				}

				if _, flaged := tmp["final"]; flaged {
					c.JSON(200, gin.H{
						"code": 0,
						"msg":  "ok",
						"data": tmp["result"],
					})
					return
				}
			}
		}

		c.JSON(200, gin.H{
			"code": 1,
			"msg":  "获取失败",
		})
		return
	})
	
	r.Run(":" + port)
	
}

func mp3ToWav(path string) bool {
	ffmpeg := "/usr/bin/ffmpeg"
	if runtime.GOOS == "windows" {
		ffmpeg = "ffmpeg.exe"
	}

	outputFile := strings.ReplaceAll(path, ".mp3", ".wav")
	cmd := exec.Command(ffmpeg, "-i", path, "-acodec pcm_s16le -ar 16k -ac 1", outputFile, "-y")
	err := cmd.Run()
	fmt.Println("cmd: ", ffmpeg, "-i", path, "-acodec pcm_s16le -ar 16k -ac 1", outputFile, "-y")
	fmt.Println("格式转换：", err)
	if err != nil {
		return false
	} else {
		return true
	}
}
